var runtimeConfig = null;

exports._initRuntime = function() {
    runtimeConfig = gConfRuntime.battleWorld;
}

function isOpen() {
    if (!gConfGlobalServer.ServerStartTime || !gConfGlobalServer.FirstBattleWorldTime ||
            !gConfGlobalServer.BattleWorldHost || !gConfGlobalServer.BattleWorldPort ||
            Date.getStamp() < gConfGlobalServer.FirstBattleWorldTime) {
        return false;
    }
    return true;
}


exports.auto_register = function(callback) {
    do {
        if (!isOpen()) {
            break;
        }

        var schedule = runtimeConfig.getSchedule();
        if (schedule.step != 'register' || !schedule.keep) {
            break;
        }

        var ranks = gRank.getRewardRanks();
        var top100Ranks = {};
        for (var id in ranks) {
            var rank = +ranks[id];
            if (rank <= gConfGlobal.BattleWorldRankMin) {
                top100Ranks[id] = rank;
            } 
        }

        // 报名请求
        var req = {mod:'battleworld', act:'register', args:{}};
        var resp = {code:0, desc:'', data:{}}; 
        req.uid = 1;
        req.args.server = config.ServerId;
        req.args.users = top100Ranks;
        requestBattleWorld(req, resp, function(){
            callback && callback();
        });
        return;
    } while (false);

    callback && callback();
}

exports.register = function(player, req, resp, onHandled) {
    do {
        if (!isOpen()) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var schedule = runtimeConfig.getSchedule();
        if (schedule.step != 'register' || !schedule.keep) {
            resp.code = 1; resp.desc = 'not register time'; break;
        }

        var ranks = gRank.getRewardRanks();
        var top100Ranks = {};
        for (var id in ranks) {
            var rank = +ranks[id];
            if (rank <= gConfGlobal.BattleWorldRankMin) {
                top100Ranks[id] = rank;
            } 
        }

        req.args.server = config.ServerId;
        req.args.users = top100Ranks;
        requestBattleWorld(req, resp, function(){
            onHandled();
        });
        return;
    } while (false);

    onHandled();

}

exports.get = function(player, req, resp, onHandled) {
    if (!isOpen()) {
        resp.code = 1; resp.desc = 'not open'; onHandled(); return;
    }

    if (!player.checkBattleWorldGuard(1)) {
        resp.data.debug = player.user.battle_world;
        resp.code = 1; resp.desc = 'guard limit'; onHandled(); return;
    }

    var user = player.user;
    var battleWorld = user.battle_world; 
    req.args.support = battleWorld.support;
    req.args.count = battleWorld.count;
    req.args.server = config.ServerId;

    requestBattleWorld(req, resp, function(){
        if( 0 == resp.code && !resp.data.calculating ) {
            if( user.status.level < gConfGlobal.BattleWorldLevelMin ) {
                resp.data.qualification = 0; 
            }
            
            // 清理上一次决战天下时的支持数据
            var support = battleWorld.support;
            var retCount = resp.data.count; 
            if( retCount && (battleWorld.count != retCount) ) {
                player.battleWorldSaveTeam = true;
                user.battle_world.support = {};
                user.battle_world.count = retCount; 
                user.battle_world.final_reward = 0; 
                user.battle_world.reward = 0; 
                user.battle_world.buy_energy = 0;

                player.markDirty('battle_world');
                support = {};
                resp.data.support = {};
            }
            
            // 更新当前玩家的支持数据
            if( resp.data.support_updates ) {
                var supportUpdates = resp.data.support_updates; 
                for( var progress in supportUpdates ) {
                    support[progress].succ = 1; 
                    player.markDirty(util.format('battle_world.support.%d.succ', progress));

                    if( supportUpdates[progress] ) {
                        support[progress].got = 1;
                        player.markDirty(util.format('battle_world.support.%d.got', progress));
                        var addGold = gConfLevel[support[progress].level].BattleWorldSupport
                                    * gConfBattleWorldSupport[progress].Gold * 10000; 

                        var awards = [['user', 'gold', addGold]];
                        resp.data.awards = player.addAwards(awards);
                    }
                }

                resp.data.support = support;
            }
        }

        resp.data.debug = player.user.battle_world;
        onHandled();
    });
}

exports.support = function(player, req, resp, onHandled) {
    var user = player.user;
    var support = user.battle_world.support;
    var supportServer = parseInt(req.args.id);
    var supportProgress = req.args.progress;

    do {
        if (!isOpen()) {
            resp.code = 1; resp.desc = 'round not open'; break;
        }

        if( isNaN(supportServer) || isNaN(supportProgress) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        if( user.status.level < gConfGlobal.BattleWorldSupportLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }  

        if( !(supportProgress in gConfBattleWorldSupport) ) {
            resp.code = 1; resp.desc = 'invalid progress'; break;
        }         

        if( supportProgress in support ) {
            resp.code = 1; resp.desc = 'already support'; break;
        }

    }while(false);

    if( resp.code == 1 ) {
        onHandled();
        return;
    }  
    
    req.args.support = support; 
    req.args.level = user.status.level;
    req.args.server = config.ServerId;

    requestBattleWorld(req, resp, function(){
        if( 0 == resp.code && !resp.data.calculating ) {
            support[supportProgress] = {
                server : supportServer,
                got : 0,
                level : user.status.level,
                succ : 0,   
            }; 

            
            player.markDirty(util.format('battle_world.support.%d', supportProgress));
            
            var retCount = resp.data.count;
            if( retCount && (user.battle_world.count != retCount) ) {
                user.battle_world.count = retCount; 
                player.markDirty('battle_world.count');
            }
        }

        onHandled();
    });
}

exports.get_battle_field = function(player, req, resp, onHandled) {
    var user = player.user;
    do {
        if (!isOpen()) {
            resp.code = 1; resp.desc = 'round not open'; break;
        }

        if( user.status.level < gConfGlobal.BattleWorldUserLevelMin ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        if (!player.checkBattleWorldGuard(1)) {
            resp.code = 1; resp.desc = 'guard limit'; break;
        }
    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }

    // 报名前先重新计算最新的上阵武将信息
    player.getFightForce();
    
    if( player.battleWorldSaveTeam ) {
    
        var userCopy = {};
        var fields = ['_id','info','status','role','team', 'pet', 'special_role'];
        for( var i = 0, len = fields.length; i < len; i++) {
            var field = fields[i];
            userCopy[field]  = user[field];
        }

        userCopy['_role_attr'] = player.roleAttrs;
        req.args.user = userCopy;
    }

    req.args.server = config.ServerId; 

    requestBattleWorld(req, resp, function(){
        delete req.args.user;
        if( 0 == resp.code && !resp.data.calculating ) {
            player.battleWorldSaveTeam = false;

            var battleWorld = user.battle_world
            var now = common.getTime();
            if( resp.data.enter ) {
                battleWorld.energy = 0;
                battleWorld.energy_time = now; 
                battleWorld.move_time = now;
                battleWorld.move = 1;

                player.markDirty('battle_world.energy');
                player.markDirty('battle_world.energy_time');
                player.markDirty('battle_world.move_time');
                player.markDirty('battle_world.move');
            }

            // 更新迁徙次数
            var moveOutputPeriod = gConfGlobal.BattleWorldMoveOutputHours * 3600;
            var addMove = parseInt((now - battleWorld.move_time) / moveOutputPeriod); 
            if( addMove ) {
                battleWorld.move += addMove; 
                battleWorld.move_time += addMove * moveOutputPeriod; 

                player.markDirty('battle_world.move');
                player.markDirty('battle_world.move_time');
            }

            resp.data.move = battleWorld.move;
            resp.data.last_fight_time = battleWorld.last_fight_time;
        }

        onHandled();
    });
}

exports.get_battle_field_city = function(player, req, resp, onHandled) {
    var user = player.user;
    do {
        if (!isOpen()) {
            resp.code = 1; resp.desc = 'round not open'; break;
        }

        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        if( user.status.level < gConfGlobal.BattleWorldUserLevelMin ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        if (!player.checkBattleWorldGuard(1)) {
            resp.code = 1; resp.desc = 'guard limit'; break;
        }
    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }

    requestBattleWorld(req, resp, function(){
        if( 0 == resp.code && !resp.data.calculating ) {
            player.updateBattleWorldEnergy();
            resp.data.energy = user.battle_world.energy;
        }

        onHandled();
    });
}

exports.get_person_rank = function(player, req, resp, onHandled) {
    var user = player.user;
    do {
        if (!isOpen()) {
            resp.code = 1; resp.desc = 'round not open'; break;
        }

        if( user.status.level < gConfGlobal.BattleWorldUserLevelMin ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }

    requestBattleWorld(req, resp, function(){
        onHandled();
    });
}

exports.fight = function(player, req, resp, onHandled) {
    var user = player.user;
    do {
        if (!isOpen()) {
            resp.code = 1; resp.desc = 'round not open'; break;
        }

        if( user.status.level < gConfGlobal.BattleWorldUserLevelMin ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var now = common.getTime();
        var lastFightTime = user.battle_world.last_fight_time;
        if( (now - lastFightTime) < gConfGlobal.BattleWorldAttackCoolTime - 1 ) {
            resp.code = 1; resp.desc = 'in cold time'; break;
        } 

        if (!player.checkBattleWorldGuard(1)) {
            resp.code = 1; resp.desc = 'guard limit'; break;
        }

    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }

    requestBattleWorld(req, resp, function(){

        if( 0 == resp.code && !resp.data.calculating ) {
            user.battle_world.last_fight_time = common.getTime();
            player.markDirty('battle_world.last_fight_time'); 
        }

        onHandled();
    });
}

exports.move = function(player, req, resp, onHandled) {
    var user = player.user;
    do {
        if (!isOpen()) {
            resp.code = 1; resp.desc = 'round not open'; break;
        }

        if( user.status.level < gConfGlobal.BattleWorldUserLevelMin ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        if( user.battle_world.move < 1 ) {
            resp.code = 1; resp.desc = 'no move'; break;
        }

    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }

    requestBattleWorld(req, resp, function(){
        if( 0 == resp.code && !resp.data.calculating ) {
            user.battle_world.move -= 1;
            player.markDirty('battle_world.move');
        }

        onHandled();
    });
}

exports.get_energy = function(player, req, resp, onHandled) {
    var user = player.user;
    var battleWorld = user.battle_world;
    do {
        if (!isOpen()) {
            resp.code = 1; resp.desc = 'round not open'; break;
        }

        if( user.status.level < gConfGlobal.BattleWorldUserLevelMin ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        player.updateBattleWorldEnergy();
        if( battleWorld.energy <= 0 ) {
            resp.code = 1; resp.desc = 'not enough energy'; break;
        }

    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }

    req.args.energy = battleWorld.energy;
    requestBattleWorld(req, resp, function(){
        if( 0 == resp.code && !resp.data.calculating ) {
            battleWorld.energy -= resp.data.energy_got;
            player.markDirty('battle_world.energy');

            resp.data.energy = battleWorld.energy;
        }

        onHandled();
    });
}

exports.buy_move = function(player, req, resp, onHandled) {
    var user = player.user;
    do {
        if (!isOpen()) {
            resp.code = 1; resp.desc = 'round not open'; break;
        }

        if( user.status.level < gConfGlobal.BattleWorldUserLevelMin ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var battleWorld = user.battle_world;
        var costCash = gConfGlobal.BattleWorldBuyMoveCash;
        if( !player.costResource('cash', costCash) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        battleWorld.move += 1;
        player.markDirty('battle_world.move');

        resp.data.cash = -costCash;

    }while(false);

    onHandled();
}

exports.buy_energy = function(player, req, resp, onHandled) {
    var user = player.user;
    do {
        if (!isOpen()) {
            resp.code = 1; resp.desc = 'round not open'; break;
        }

        if( user.status.level < gConfGlobal.BattleWorldUserLevelMin ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var battleWorld = user.battle_world;
        var buyConf = gConfBuy[battleWorld.buy_energy + 1];
        if( !buyConf || !buyConf.CashBattleWorldEnergy ) {
            resp.code = 1; resp.desc = 'no times'; break;
        }
        
        var costCash = buyConf.CashBattleWorldEnergy;
        if( !player.costResource('cash', costCash, battleWorld.buy_energy) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        battleWorld.buy_energy += 1;
        battleWorld.energy += gConfGlobal.BattleWorldEnergyPerCost; 

        player.markDirty('battle_world.buy_energy');
        player.markDirty('battle_world.energy');

        resp.data.cash = -costCash;
    }while(false);

    onHandled();
}

exports.end_war = function(player, req, resp, onHandled) {
    if (!player.checkBattleWorldGuard(1)) {
        resp.code = 1; resp.desc = 'guard limit'; onHandled(); return;
    }

    var user = player.user;
    requestBattleWorld(req, resp, function(){
        onHandled();
    });
}

exports.get_reward = function(player, req, resp, onHandled) {
    if (!isOpen()) {
        resp.code = 1; resp.desc = 'round not open'; onHandled(); return;
    }

    var user = player.user;
    req.args.reward = user.battle_world.reward;
    requestBattleWorld(req, resp, function(){
        if( 0 == resp.code && !resp.data.calculating ) {
            if( resp.data.topone ) {
                resp.data.awards = player.addAwards([['material',gConfGlobal.BattleWorldExtraMaterialId,1]]);
            }

            if( resp.data.progress ) {
                user.battle_world.reward = resp.data.progress;
                player.markDirty('battle_world.reward');
                var awards = [['user', 'soul', resp.data.soul]];
                player.addAwards(awards);
            }

        }

        onHandled();
    });
}

exports.get_final_reward = function(player, req, resp, onHandled) {
    if (!isOpen()) {
        resp.code = 1; resp.desc = 'round not open'; onHandled(); return;
    }

    var user = player.user;
    if( user.battle_world.final_reward ) {
        resp.code = 1; 
        resp.desc = 'got'; 
        onHandled();
        return;
    }
    
    req.args.server = config.ServerId; 

    requestBattleWorld(req, resp, function(){
        if( 0 == resp.code && !resp.data.calculating ) {
            if( resp.data.awards ) {
                resp.data.awards = player.addAwards(resp.data.awards);
                user.battle_world.final_reward = 1;
                player.markDirty('battle_world.final_reward');
            }
        }

        onHandled();
    });
}

exports.get_report = function(player, req, resp, onHandled) {
    requestBattleWorld(req, resp, function(){
        onHandled();
    });
}

exports.get_replay = function(player, req, resp, onHandled) {
    requestBattleWorld(req, resp, function(){
        onHandled();
    });
}
